![[アップデート] CloudFormationのカスタムリソースのタイムアウト値を設定できるようになりました](https://devio2023-media.developers.io/wp-content/uploads/2023/08/aws-cloudformation.png)
[アップデート] CloudFormationのカスタムリソースのタイムアウト値を設定できるようになりました
カスタムリソース作成処理が失敗した時の虚無な時間を無くしたい
こんにちは、のんピ(@non____97)です。
皆さんはCloudFormationのカスタムリソースの作成が失敗した時の虚無な時間を無くしたいしたいなと思ったことはありますか? 私はあります。
CloudFormationカスタムリソースのタイムアウトのデフォルト値は1時間です。もし、カスタムリソースを作成するLambda関数が正常に処理できなかった場合は1時間待つことになります。加えて、スタックを正常に作成できなかった場合に発生するロールバックでも1時間待つことになるため、合計2時間虚無な時間を過ごすことになります。これは悲しいですね。
今回、アップデートによりCloudFormationのカスタムリソースのタイムアウト値を設定できるようになりました。
AWS公式ドキュメントを確認すると、タイムアウト値は1秒単位で1秒から3,600秒までで選択できるようです。
Properties
ServiceTimeout
The maximum time, in seconds, that can elapse before a custom resource operation times out.
The value must be an integer from 1 to 3600. The default value is 3600 seconds (1 hour).
Required: No
Type: String
Update requires: No interruption
これはありがたいですね。リソース作成に時間がかからないものであれば1分程度で設定する形でも良さそうです。また、同期実行するLambda関数であればLambda関数の実行タイムアウトの上限である15分で設定するのも良さそうです。
実際に試してみました。
やってみた
AWS CDKのコードの説明
今回はAWS CDKを使ってカスタムリソースを作成します。
作成するカスタムリソースはIMDSのデフォルト設定を変更するものです。具体的にはカスタムリソースの作成や更新時にはIMDSでセッショントークンを要求する = IMDSv2のみ許可し、削除時には未設定の状態にします。
AwsCustomResourceを使用した場合の同様の処理は以下記事でも紹介しています。
今回はあえてカスタムリソースのレスポンスを返さなかった場合、設定したタイムアウト値でタイムアウトをされることを確認したかったので、Lambda関数をプロバイダーとしてカスタムリソースを作成します。
AWS CDKにおけるカスタムリソースの作成方法は以下があります。
Provider | Compute Type | Error Handling | Submit to CloudFormation | Max Timeout | Language | Footprint |
---|---|---|---|---|---|---|
sns.Topic | Self-managed | Manual | Manual | Unlimited | Any | Depends |
lambda.Function | AWS Lambda | Manual | Manual | 15min | Any | Small |
core.CustomResourceProvider | AWS Lambda | Auto | Auto | 15min | Node.js | Small |
custom-resources.Provider | AWS Lambda | Auto | Auto | Unlimited Async | Any | Large |
抜粋 : Custom Resource Providers
なお、AWS CDKにおけるカスタムリソース作成時の推奨はCustom Resource Provider Framework(custom-resources.Provider)です。Custom Resource Provider Frameworkの使用方法は以下記事をご覧ください。
Lambda関数で実行するコードは以下のとおりです。
import boto3 from botocore.exceptions import ClientError import cfnresponse ec2_client = boto3.client("ec2") def lambda_handler(event, context): print("Received event:", event) print(boto3.__version__) try: request_type = event["RequestType"] if request_type == "Create": on_create() elif request_type == "Update": on_update() elif request_type == "Delete": on_delete() else: raise ValueError("Invalid request type") cfnresponse.send(event, context, cfnresponse.SUCCESS, {"Response": "Success"}) except Exception as e: print("Error:", e) cfnresponse.send(event, context, cfnresponse.FAILED, {}) def on_create() -> None: modify_instance_metadata_defaults(HttpTokens="required") def on_update() -> None: modify_instance_metadata_defaults(HttpTokens="required") def on_delete() -> None: modify_instance_metadata_defaults(HttpTokens="no-preference") def modify_instance_metadata_defaults(HttpTokens: str) -> None: try: response = ec2_client.modify_instance_metadata_defaults(HttpTokens=HttpTokens) print(response) except ClientError as e: print(e)
使用しているmodify_instance_metadata_defaultsですが、LambdaのPython 3.12ランタイムにインストールされているboto3のバージョンは1.34.42に含まれていないようでした。
そのため、最新のboto3をバンドルしたLambda Layerを作成し、Lambda関数にアタッチしています。boto3はデプロイ前に以下のように指定したディレクトリにインストールしています。
$ mkdir -p lib/src/lambda/python $ pip3 install boto3 -t ./lib/src/lambda/layer/python Collecting boto3 Downloading boto3-1.34.129-py3-none-any.whl.metadata (6.6 kB) Collecting botocore<1.35.0,>=1.34.129 (from boto3) Downloading botocore-1.34.129-py3-none-any.whl.metadata (5.7 kB) Collecting jmespath<2.0.0,>=0.7.1 (from boto3) Downloading jmespath-1.0.1-py3-none-any.whl.metadata (7.6 kB) Collecting s3transfer<0.11.0,>=0.10.0 (from boto3) Downloading s3transfer-0.10.1-py3-none-any.whl.metadata (1.7 kB) Collecting python-dateutil<3.0.0,>=2.1 (from botocore<1.35.0,>=1.34.129->boto3) Downloading python_dateutil-2.9.0.post0-py2.py3-none-any.whl.metadata (8.4 kB) Collecting urllib3!=2.2.0,<3,>=1.25.4 (from botocore<1.35.0,>=1.34.129->boto3) Downloading urllib3-2.2.2-py3-none-any.whl.metadata (6.4 kB) Collecting six>=1.5 (from python-dateutil<3.0.0,>=2.1->botocore<1.35.0,>=1.34.129->boto3) Downloading six-1.16.0-py2.py3-none-any.whl.metadata (1.8 kB) Downloading boto3-1.34.129-py3-none-any.whl (139 kB) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 139.2/139.2 kB 2.0 MB/s eta 0:00:00 Downloading botocore-1.34.129-py3-none-any.whl (12.3 MB) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 12.3/12.3 MB 13.1 MB/s eta 0:00:00 Downloading jmespath-1.0.1-py3-none-any.whl (20 kB) Downloading s3transfer-0.10.1-py3-none-any.whl (82 kB) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 82.2/82.2 kB 5.9 MB/s eta 0:00:00 Downloading python_dateutil-2.9.0.post0-py2.py3-none-any.whl (229 kB) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 229.9/229.9 kB 7.2 MB/s eta 0:00:00 Downloading urllib3-2.2.2-py3-none-any.whl (121 kB) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 121.4/121.4 kB 15.7 MB/s eta 0:00:00 Downloading six-1.16.0-py2.py3-none-any.whl (11 kB) Installing collected packages: urllib3, six, jmespath, python-dateutil, botocore, s3transfer, boto3 Successfully installed boto3-1.34.129 botocore-1.34.129 jmespath-1.0.1 python-dateutil-2.9.0.post0 s3transfer-0.10.1 six-1.16.0 urllib3-2.2.2
また、本題のカスタムリソースのタイムアウト値は10秒に設定しました。
スタックを作成するコードは以下のとおりです。
import * as cdk from "aws-cdk-lib"; import { Construct } from "constructs"; import * as path from "path"; import * as fs from "fs"; export class CustomResourceStack extends cdk.Stack { constructor(scope: Construct, id: string, props?: cdk.StackProps) { super(scope, id, props); // Lambda Function const imdsv2Lambda = new cdk.aws_lambda.SingletonFunction( this, "Imdsv2Lambda", { code: new cdk.aws_lambda.InlineCode( fs.readFileSync( path.join(__dirname, "./src/lambda/imdsv2/index.py"), { encoding: "utf-8" } ) ), uuid: "975fff39-68dd-41c1-af55-3e7af5ec9ee6", handler: "index.lambda_handler", runtime: cdk.aws_lambda.Runtime.PYTHON_3_12, architecture: cdk.aws_lambda.Architecture.ARM_64, loggingFormat: cdk.aws_lambda.LoggingFormat.JSON, } ); imdsv2Lambda.role?.addManagedPolicy( new cdk.aws_iam.ManagedPolicy( this, "ModifyInstanceMetadataDefaultsPolicy", { statements: [ new cdk.aws_iam.PolicyStatement({ actions: ["ec2:ModifyInstanceMetadataDefaults"], resources: ["*"], }), ], } ) ); // Lambda Layer const boto3Layer = new cdk.aws_lambda.LayerVersion(this, "Boto3Layer", { code: cdk.aws_lambda.AssetCode.fromAsset( path.join(__dirname, "./src/lambda/layer") ), compatibleRuntimes: [cdk.aws_lambda.Runtime.PYTHON_3_12], compatibleArchitectures: [cdk.aws_lambda.Architecture.ARM_64], }); imdsv2Lambda.addLayers(boto3Layer); // Custom Resource const customResource = new cdk.CustomResource(this, "CustomResource", { serviceToken: imdsv2Lambda.functionArn, properties: { ServiceTimeout: 10 }, }); } }
スタックのデプロイ
スタックをデプロイする前にIMDSデフォルトの設定値を確認しておきます。全てNo preference
です。
それでは、npx cdk deploy
でスタックをデプロイします。
デプロイ後、IMDSデフォルトの設定値を確認するとMetadata versionがV2 only (token required)
に変わりました。カスタムリソースで意図したとおりに設定されていますね。
スタックのリソース一覧は以下のようになっています。2024/06/19/[$LATEST]feeda2f59f4540c5aed490b0c8c69baf
という物理名のカスタムリソースが作成されていますね。
カスタムリソースを作成するLambda関数が出力したログは以下のとおりです。受け取ったイベントに'ServiceTimeout': '10'
が含まれていますね。
{ "time": "2024-06-19T08:45:24.255Z", "type": "platform.initStart", "record": { "initializationType": "on-demand", "phase": "init", "runtimeVersion": "python:3.12.v28", "runtimeVersionArn": "arn:aws:lambda:us-east-1::runtime:68a46227c0fb5718a1bbf0378fdf0e66719fd3fac7a8aea038370a0343198447", "functionName": "CustomResourceStack-SingletonLambda975fff3968dd41c-L5DiFbl4LYio", "functionVersion": "$LATEST" } } { "timestamp": "2024-06-19T08:45:24Z", "level": "INFO", "message": "Found credentials in environment variables.", "logger": "botocore.credentials", "requestId": "" } { "time": "2024-06-19T08:45:25.096Z", "type": "platform.start", "record": { "requestId": "7e17d3e5-f1aa-4983-a734-379b5da774ad", "version": "$LATEST" } } Received event: {'RequestType': 'Create', 'ServiceToken': 'arn:aws:lambda:us-east-1:<AWSアカウントID>:function:CustomResourceStack-SingletonLambda975fff3968dd41c-L5DiFbl4LYio', 'ServiceTimeout': '10', 'ResponseURL': 'https://cloudformation-custom-resource-response-useast1.s3.amazonaws.com/arn%3Aaws%3Acloudformation%3Aus-east-1%3A<AWSアカウントID>%3Astack/CustomResourceStack/220b3f70-2e18-11ef-bdf1-0e5a89a0c50b%7CCustomResource%7C97a94ddd-e81a-4ee2-ac54-1c3da3408e09 'StackId': 'arn:aws:cloudformation:us-east-1:<AWSアカウントID>:stack/CustomResourceStack/220b3f70-2e18-11ef-bdf1-0e5a89a0c50b', 'RequestId': '97a94ddd-e81a-4ee2-ac54-1c3da3408e09', 'LogicalResourceId': 'CustomResource', 'ResourceType': 'AWS::CloudFormation::CustomResource', 'ResourceProperties': {'ServiceToken': 'arn:aws:lambda:us-east-1:<AWSアカウントID>:function:CustomResourceStack-SingletonLambda975fff3968dd41c-L5DiFbl4LYio', 'ServiceTimeout': '10'}} 1.34.129 {'Return': True, 'ResponseMetadata': {'RequestId': '123b29ab-8fc4-4b57-91ed-2b59e19bcbce', 'HTTPStatusCode': 200, 'HTTPHeaders': {'x-amzn-requestid': '123b29ab-8fc4-4b57-91ed-2b59e19bcbce', 'cache-control': 'no-cache, no-store', 'strict-transport-security': 'max-age=31536000; includeSubDomains', 'vary': 'accept-encoding', 'content-type': 'text/xml;charset=UTF-8', 'transfer-encoding': 'chunked', 'date': 'Wed, 19 Jun 2024 08:45:25 GMT', 'server': 'AmazonEC2'}, 'RetryAttempts': 0}} https://cloudformation-custom-resource-response-useast1.s3.amazonaws.com/arn%3Aaws%3Acloudformation%3Aus-east-1%3A<AWSアカウントID>%3Astack/CustomResourceStack/220b3f70-2e18-11ef-bdf1-0e5a89a0c50b%7CCustomResource%7C97a94ddd-e81a-4ee2-ac54-1c3da3408e09 Response body: { "Status": "SUCCESS", "Reason": "See the details in CloudWatch Log Stream: 2024/06/19/[$LATEST]feeda2f59f4540c5aed490b0c8c69baf", "PhysicalResourceId": "2024/06/19/[$LATEST]feeda2f59f4540c5aed490b0c8c69baf", "StackId": "arn:aws:cloudformation:us-east-1:<AWSアカウントID>:stack/CustomResourceStack/220b3f70-2e18-11ef-bdf1-0e5a89a0c50b", "RequestId": "97a94ddd-e81a-4ee2-ac54-1c3da3408e09", "LogicalResourceId": "CustomResource", "NoEcho": false, "Data": { "Response": "Success" } } Status code: 200 { "time": "2024-06-19T08:45:26.740Z", "type": "platform.report", "record": { "requestId": "7e17d3e5-f1aa-4983-a734-379b5da774ad", "metrics": { "durationMs": 1643.427, "billedDurationMs": 1644, "memorySizeMB": 128, "maxMemoryUsedMB": 88, "initDurationMs": 839.541 }, "status": "success" } }
スタックの削除
npx cdk destroy
でスタックを削除した時の挙動も確認します。
スタックを削除すると、以下のようにNo preference
に戻っていました。
意図したとおりですね。
カスタムリソースを作成するLambda関数が出力したログは以下のとおりです。Deleteリクエストを受け取って動作したことが分かります。
{ "time": "2024-06-19T08:48:04.383Z", "type": "platform.start", "record": { "requestId": "7250ee94-c331-4906-abaf-ec8dd0f44cfa", "version": "$LATEST" } } Received event: {'RequestType': 'Delete', 'ServiceToken': 'arn:aws:lambda:us-east-1:<AWSアカウントID>:function:CustomResourceStack-SingletonLambda975fff3968dd41c-L5DiFbl4LYio', 'ServiceTimeout': '10', 'ResponseURL': 'https://cloudformation-custom-resource-response-useast1.s3.amazonaws.com/arn%3Aaws%3Acloudformation%3Aus-east-1%3A<AWSアカウントID>%3Astack/CustomResourceStack/220b3f70-2e18-11ef-bdf1-0e5a89a0c50b%7CCustomResource%7C1ae0ca16-f35c-4a34-9ce7-a641ad960524 'StackId': 'arn:aws:cloudformation:us-east-1:<AWSアカウントID>:stack/CustomResourceStack/220b3f70-2e18-11ef-bdf1-0e5a89a0c50b', 'RequestId': '1ae0ca16-f35c-4a34-9ce7-a641ad960524', 'LogicalResourceId': 'CustomResource', 'PhysicalResourceId': '2024/06/19/[$LATEST]feeda2f59f4540c5aed490b0c8c69baf', 'ResourceType': 'AWS::CloudFormation::CustomResource', 'ResourceProperties': {'ServiceToken': 'arn:aws:lambda:us-east-1:<AWSアカウントID>:function:CustomResourceStack-SingletonLambda975fff3968dd41c-L5DiFbl4LYio', 'ServiceTimeout': '10'}} 1.34.129 {'Return': True, 'ResponseMetadata': {'RequestId': 'e3527b88-08a1-4ef7-9605-c5db275ce1ee', 'HTTPStatusCode': 200, 'HTTPHeaders': {'x-amzn-requestid': 'e3527b88-08a1-4ef7-9605-c5db275ce1ee', 'cache-control': 'no-cache, no-store', 'strict-transport-security': 'max-age=31536000; includeSubDomains', 'vary': 'accept-encoding', 'content-type': 'text/xml;charset=UTF-8', 'transfer-encoding': 'chunked', 'date': 'Wed, 19 Jun 2024 08:48:04 GMT', 'server': 'AmazonEC2'}, 'RetryAttempts': 0}} https://cloudformation-custom-resource-response-useast1.s3.amazonaws.com/arn%3Aaws%3Acloudformation%3Aus-east-1%3A<AWSアカウントID>%3Astack/CustomResourceStack/220b3f70-2e18-11ef-bdf1-0e5a89a0c50b%7CCustomResource%7C1ae0ca16-f35c-4a34-9ce7-a641ad960524 Response body: { "Status": "SUCCESS", "Reason": "See the details in CloudWatch Log Stream: 2024/06/19/[$LATEST]feeda2f59f4540c5aed490b0c8c69baf", "PhysicalResourceId": "2024/06/19/[$LATEST]feeda2f59f4540c5aed490b0c8c69baf", "StackId": "arn:aws:cloudformation:us-east-1:<AWSアカウントID>:stack/CustomResourceStack/220b3f70-2e18-11ef-bdf1-0e5a89a0c50b", "RequestId": "1ae0ca16-f35c-4a34-9ce7-a641ad960524", "LogicalResourceId": "CustomResource", "NoEcho": false, "Data": { "Response": "Success" } } Status code: 200 { "time": "2024-06-19T08:48:05.956Z", "type": "platform.report", "record": { "requestId": "7250ee94-c331-4906-abaf-ec8dd0f44cfa", "metrics": { "durationMs": 1572.29, "billedDurationMs": 1573, "memorySizeMB": 128, "maxMemoryUsedMB": 88 }, "status": "success" } }
cfn-responseの記述を削除してスタックをデプロイ
Lamnda関数内のcfn-responseの記述を削除してスタックをデプロイします。
以下のようにcfnresponse.send()
をコメントアウトしました。
import boto3 from botocore.exceptions import ClientError import cfnresponse ec2_client = boto3.client("ec2") def lambda_handler(event, context): print("Received event:", event) print(boto3.__version__) try: request_type = event["RequestType"] if request_type == "Create": on_create() elif request_type == "Update": on_update() elif request_type == "Delete": on_delete() else: raise ValueError("Invalid request type") # cfnresponse.send(event, context, cfnresponse.SUCCESS, {"Response": "Success"}) except Exception as e: print("Error:", e) # cfnresponse.send(event, context, cfnresponse.FAILED, {"Response": "Success"}) def on_create() -> None: modify_instance_metadata_defaults(HttpTokens="required") def on_update() -> None: modify_instance_metadata_defaults(HttpTokens="required") def on_delete() -> None: modify_instance_metadata_defaults(HttpTokens="no-preference") def modify_instance_metadata_defaults(HttpTokens: str) -> None: try: response = ec2_client.modify_instance_metadata_defaults(HttpTokens=HttpTokens) print(response) except ClientError as e: print(e)
デプロイしようとしたところ、作成およびロールバックのための削除に失敗しました。
$ npx cdk deploy ✨ Synthesis time: 9.45s CustomResourceStack: start: Building e8ed7ffb26ddc803a6c269dd9b83c0099a140224fafabe325bf3902cf15023d6:current_account-current_region CustomResourceStack: success: Built e8ed7ffb26ddc803a6c269dd9b83c0099a140224fafabe325bf3902cf15023d6:current_account-current_region CustomResourceStack: start: Publishing e8ed7ffb26ddc803a6c269dd9b83c0099a140224fafabe325bf3902cf15023d6:current_account-current_region CustomResourceStack: success: Published e8ed7ffb26ddc803a6c269dd9b83c0099a140224fafabe325bf3902cf15023d6:current_account-current_region This deployment will make potentially sensitive changes according to your current security approval level (--require-approval broadening). Please confirm you intend to make the following modifications: IAM Statement Changes ┌───┬────────────────────────────────────────────────────────────────────┬────────┬────────────────┬──────────────────────────────┬───────────┐ │ │ Resource │ Effect │ Action │ Principal │ Condition │ ├───┼────────────────────────────────────────────────────────────────────┼────────┼────────────────┼──────────────────────────────┼───────────┤ │ + │ ${SingletonLambda975fff3968dd41c1af553e7af5ec9ee6/ServiceRole.Arn} │ Allow │ sts:AssumeRole │ Service:lambda.amazonaws.com │ │ └───┴────────────────────────────────────────────────────────────────────┴────────┴────────────────┴──────────────────────────────┴───────────┘ IAM Policy Changes ┌───┬────────────────────────────────────────────────────────────────┬────────────────────────────────────────────────────────────────────────────────┐ │ │ Resource │ Managed Policy ARN │ ├───┼────────────────────────────────────────────────────────────────┼────────────────────────────────────────────────────────────────────────────────┤ │ + │ ${SingletonLambda975fff3968dd41c1af553e7af5ec9ee6/ServiceRole} │ arn:${AWS::Partition}:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole │ │ + │ ${SingletonLambda975fff3968dd41c1af553e7af5ec9ee6/ServiceRole} │ ${ModifyInstanceMetadataDefaultsPolicy} │ └───┴────────────────────────────────────────────────────────────────┴────────────────────────────────────────────────────────────────────────────────┘ (NOTE: There may be security-related changes not in this list. See https://github.com/aws/aws-cdk/issues/1299) Do you wish to deploy these changes (y/n)? y CustomResourceStack: deploying... [1/1] CustomResourceStack: creating CloudFormation changeset... 15:02:37 | CREATE_FAILED | AWS::CloudFormation::CustomResource | CustomResource CloudFormation did not receive a response from your Custom Resource. Please check your logs for requestId [5fcf076e-ed00-4b8b-957a-c88df3d5a7a7]. If you are using the Python cfn-response module, you may ne ed to update your Lambda function code so that CloudFormation can attach the updated version. 15:03:01 | DELETE_FAILED | AWS::CloudFormation::CustomResource | CustomResource CloudFormation did not receive a response from your Custom Resource. Please check your logs for requestId [63fea4e8-c41c-4403-a182-b1dc03fa381f]. If you are using the Python cfn-response module, you may ne ed to update your Lambda function code so that CloudFormation can attach the updated version. ❌ CustomResourceStack failed: Error: The stack named CustomResourceStack failed creation, it may need to be manually deleted from the AWS console: ROLLBACK_FAILED (The following resource(s) failed to delete: [CustomResource]. ): CloudFormation did not receive a response from your Custom Resource. Please check your logs for requestId [5fcf076e-ed00-4b8b-957a-c88df3d5a7a7]. If you are using the Python cfn-response module, you may need to update your Lambda function code so that CloudFormation can attach the updated version. at FullCloudFormationDeployment.monitorDeployment (/<ディレクトリパス>/custom-resource/node_modules/aws-cdk/lib/index.js:451:10568) at process.processTicksAndRejections (node:internal/process/task_queues:95:5) at async Object.deployStack2 [as deployStack] (/<ディレクトリパス>/custom-resource/node_modules/aws-cdk/lib/index.js:454:199515) at async /<ディレクトリパス>/custom-resource/node_modules/aws-cdk/lib/index.js:454:181237 ❌ Deployment failed: Error: The stack named CustomResourceStack failed creation, it may need to be manually deleted from the AWS console: ROLLBACK_FAILED (The following resource(s) failed to delete: [CustomResource]. ): CloudFormation did not receive a response from your Custom Resource. Please check your logs for requestId [5fcf076e-ed00-4b8b-957a-c88df3d5a7a7]. If you are using the Python cfn-response module, you may need to update your Lambda function code so that CloudFormation can attach the updated version. at FullCloudFormationDeployment.monitorDeployment (/<ディレクトリパス>/custom-resource/node_modules/aws-cdk/lib/index.js:451:10568) at process.processTicksAndRejections (node:internal/process/task_queues:95:5) at async Object.deployStack2 [as deployStack] (/<ディレクトリパス>/custom-resource/node_modules/aws-cdk/lib/index.js:454:199515) at async /<ディレクトリパス>/custom-resource/node_modules/aws-cdk/lib/index.js:454:181237 The stack named CustomResourceStack failed creation, it may need to be manually deleted from the AWS console: ROLLBACK_FAILED (The following resource(s) failed to delete: [CustomResource]. ): CloudFormation did not receive a response from your Custom Resource. Please check your logs for requestId [5fcf076e-ed00-4b8b-957a-c88df3d5a7a7]. If you are using the Python cfn-response module, you may need to update your Lambda function code so that CloudFormation can attach the updated version.
マネジメントコンソールでスタックのイベントを確認すると、カスタムリソースを作成および削除しようとして10秒を超過するとCloudFormation did not receive a response from your Custom Resource
とエラーになっていることが分かります。
Lambda関数のコード側で不具合があったとしても、適切なタイムアウト値を設定していれば虚無な時間を過ごすことはなくなりそうです。
カスタムリソースを使用する時の必須設定レベル
CloudFormationのカスタムリソースのタイムアウト値を設定できるようになったアップデートを紹介しました。
カスタムリソースの作成に1時間処理に時間がかかるケースも稀だと思うので、カスタムリソースを使用する時の必須設定レベルだなと感じています。上手に使えばカスタムリソースを使ったデプロイが加速させることができそうです。
この記事が誰かの助けになれば幸いです。
以上、AWS事業本部 コンサルティング部の のんピ(@non____97)でした!